package com.logic.landseaserver.common.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.logic.common.exception.BusinessException;
import com.logic.landseaserver.common.enums.WeChatMsgEnum;

import net.sf.json.JSONObject;

@Service
public class WeChatUtil implements EnvironmentAware
{
    private static final Logger LOG = LoggerFactory.getLogger(WeChatUtil.class);
    
    private static final String ENV_WECHAT = "logic.wechat.";
    
    private static RelaxedPropertyResolver weChatpropertyResolver;
    
    private static final String CORPID = "corpid";
    
    private static final String SECRET = "secret";
    
    private static final String LOGINSECRET = "loginsecret";
    
    public static String access_token;
    
    public static String login_access_token;
    
    public static String CorpID;
    
    public static String Secret;
    
    public static String LoginSecret;
    
    public static String access_token_time;
    
    public static String login_access_token_time;
    
    public static long validateTimeLang;
    
    public static long loginValidateTimeLang;
    
    public static String ACCESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
    
    Logger logger = LoggerFactory.getLogger(WeChatUtil.class);
    
    // private static String properties = "/wechat.properties";
    // private static Properties prop = new Properties();
    private static WeChatUtil instance = new WeChatUtil();
    
    public static WeChatUtil getInstance()
    {
        return instance;
    }
    
    public String getAccessToken(String businessType)
        throws ParseException
    {
        if ("WBT0".equals(businessType))
        { // 通讯录
            if (access_token == null)
            {
                setAccessToken(businessType);
            }
            else
            {
                boolean validate = validateAccessToken(businessType);
                if (!validate)
                {
                    setAccessToken(businessType);
                }
            }
            return access_token;
        }
        else if ("WBT1".equals(businessType)) // 朗诗测试
        {
            if (login_access_token == null)
            {
                setAccessToken(businessType);
            }
            else
            {
                boolean validate = validateAccessToken(businessType);
                if (!validate)
                {
                    setAccessToken(businessType);
                }
            }
            return login_access_token;
        }
        return "错误的业务类型";
    }
    
    public String getCorpID()
    {
        return CorpID;
    }
    
    public String getSecret()
    {
        return Secret;
    }
    
    // 获取access_token
    public void setAccessToken(String businessType)
    {
        if (CorpID == null || Secret == null || LoginSecret == null)
        {
            readProperties();
            settoken(businessType);
        }
        else
        {
            settoken(businessType);
        }
    }
    
    public void settoken(String businessType)
    {
        Map<String, String> headMap = new HashMap<String, String>();
        headMap.put("Access-Control-Allow-Origin", "*");
        headMap.put("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
        headMap.put("Access-Control-Max-Age", "3600");
        headMap.put("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
        headMap.put("Access-Control-Expose-Headers",
            "MSG, STATUS, COUNT, TOTAL_COUNT, USER_ID, USER_NAME, ORG_ID, size, context, token");
        String terrSecret = null;
        if ("WBT0".equals(businessType))
        { // 通讯录
            terrSecret = Secret;
        }
        else if ("WBT1".equals(businessType))
        { // 朗诗应用
            terrSecret = LoginSecret;
        }
        String result =
            HttpRequestClient.getRequest(ACCESS_TOKEN_URL + "?corpid=" + CorpID + "&corpsecret=" + terrSecret, headMap);
        JSONObject resultobj = JSONObject.fromObject(result);
        if (resultobj.containsKey("errcode"))
        {
            JSONObject tokenjson = JSONObject.fromObject(result);
            if (tokenjson.containsKey("access_token"))
            {
                if ("WBT0".equals(businessType))
                {
                    access_token = tokenjson.getString("access_token");
                    Date nowTime = new Date(System.currentTimeMillis());
                    SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    access_token_time = sdFormatter.format(nowTime);
                    
                    validateTimeLang = Long.parseLong(tokenjson.getString("expires_in")) - 600; // 提前10分钟刷新
                }
                else if ("WBT1".equals(businessType))
                {
                    login_access_token = tokenjson.getString("access_token");
                    Date nowTime = new Date(System.currentTimeMillis());
                    SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    login_access_token_time = sdFormatter.format(nowTime);
                    
                    loginValidateTimeLang = Long.parseLong(tokenjson.getString("expires_in")) - 600; // 提前10分钟刷新
                }
                logger.info(
                    "---------------------获取access_token--------------------------获取access_token------------------------------");
                
            }
            else
            {
                String errormsg = null;
                if ("-1".equals(resultobj.getString("errcode")))
                {
                    errormsg = WeChatMsgEnum.valueOf("_1").getCode();
                }
                else
                {
                    errormsg = WeChatMsgEnum.valueOf("_" + resultobj.getString("errcode")).getCode();
                }
                try
                {
                    logger.error("微信端错误：" + errormsg);
                    throw new BusinessException("微信端错误：" + errormsg);
                }
                catch (BusinessException e)
                {
                    LOG.error("settoken error.", e);
                }
            }
        }
    }
    
    // 读取配置文件
    public void readProperties()
    {
        try
        {
            /*
             * InputStream in = WeChatUtil.class.getResourceAsStream(propertiesPath); prop.load(in); /// 加载属性列表 CorpID =
             * prop.getProperty("CorpID"); Secret = prop.getProperty("Secret"); in.close();
             */
            CorpID = weChatpropertyResolver.getProperty(CORPID, String.class);
            Secret = weChatpropertyResolver.getProperty(SECRET, String.class);
            LoginSecret = weChatpropertyResolver.getProperty(LOGINSECRET, String.class);
        }
        catch (Exception e)
        {
            LOG.error("readProperties error.", e);
        }
    }
    
    // 验证access_token时间
    public boolean validateAccessToken(String businessType)
        throws ParseException
    {
        
        Date nowTime = new Date(System.currentTimeMillis());
        SimpleDateFormat sdFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdFormatter.format(nowTime);
        
        Date d1 = sdFormatter.parse(time);
        Date d2 = null;
        Long terrValidateTimeLong = null;
        if ("WBT0".equals(businessType))
        {
            d2 = sdFormatter.parse(access_token_time);
            terrValidateTimeLong = validateTimeLang;
        }
        else if ("WBT1".equals(businessType))
        {
            d2 = sdFormatter.parse(login_access_token_time);
            terrValidateTimeLong = loginValidateTimeLang;
        }
        long diff = d1.getTime() - d2.getTime();// 这样得到的差值是微秒级别
        long seconds = (diff) / (1000);
        
        if (seconds < terrValidateTimeLong)
        {
            return true;
        }
        return false;
    }
    
    @Override
    public void setEnvironment(Environment environment)
    {
        weChatpropertyResolver = new RelaxedPropertyResolver(environment, ENV_WECHAT);
    }
}
